package Net

import (
	"fmt"
	"github.com/sentiger/ftcp/Iface"
	"github.com/sentiger/ftcp/Utils"
	"strconv"
)

type MsgHandler struct {
	Apis           map[uint32]Iface.IRouter
	WorkerPoolSize uint32
	TaskQueue      []chan Iface.IRequest
}

func NewMsgHandler() *MsgHandler {
	return &MsgHandler{
		Apis:           make(map[uint32]Iface.IRouter),
		WorkerPoolSize: Utils.GlobalObject.WorkerPoolSize,
		TaskQueue:      make([]chan Iface.IRequest, Utils.GlobalObject.WorkerPoolSize),
	}
}

// 业务处理
func (mh *MsgHandler) DoMsgHandler(request Iface.IRequest) {
	handler, ok := mh.Apis[request.GetMsgId()]
	if !ok {
		fmt.Println("api msgId = ", request.GetMsgId(), " is not FOUND!")
		return
	}
	handler.PreHandle(request)
	handler.Handle(request)
	handler.PostHandle(request)
}

// 添加业务处理
func (mh *MsgHandler) AddRouter(msgId uint32, router Iface.IRouter) {
	//1 判断当前msg绑定的API处理方法是否已经存在
	if _, ok := mh.Apis[msgId]; ok {
		panic("repeated api , msgId = " + strconv.Itoa(int(msgId)))
	}
	//2 添加msg与api的绑定关系
	mh.Apis[msgId] = router
	fmt.Println("Add api msgId = ", msgId)
}

// 启动工作进程池
func (mh *MsgHandler) StartWorkerPool() {
	for i := 0; i < int(mh.WorkerPoolSize); i++ {
		mh.TaskQueue[i] = make(chan Iface.IRequest, Utils.GlobalObject.MaxWorkerTaskLen)
		go mh.StartOneWorker(i, mh.TaskQueue[i])
	}
}

func (mh *MsgHandler) StartOneWorker(workID int, taskQueue chan Iface.IRequest) {
	fmt.Printf("启动worker[%d]成功\n", workID)
	for {
		select {
		case request := <-taskQueue:
			fmt.Printf("处理任务workerId=>%d\n", workID)
			mh.DoMsgHandler(request)
		}
	}
}

// 发送消息到任务进程，通过取模形式
func (mh *MsgHandler) SendMsgToTaskQueue(request Iface.IRequest) {
	workerID := request.GetConnection().GetConnID() % mh.WorkerPoolSize
	fmt.Println("Add ConnID=", request.GetConnection().GetConnID(), " request msgID=", request.GetMsgId(), "to workerID=", workerID)
	//将请求消息发送给任务队列
	mh.TaskQueue[workerID] <- request
}
